﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AsyncHelper.cs" company="Scrum for Team System">
//   None
// </copyright>
// <summary>
//   Defines the AsyncHelper type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ScrumForTeamSystem.Setup.SfTSConfigatorUI
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;

    /// <summary>
    /// Initializes instance of AsyncHelper
    /// </summary>
    internal static class AsyncHelper
    {
        /// <summary>
        /// Loads the async.
        /// </summary>
        /// <typeparam name="T">The list element type.</typeparam>
        /// <param name="view">The main UI.</param>
        /// <param name="loadItems">The load items.</param>
        /// <param name="updateCollection">The update collection method.</param>
        /// <param name="callback">The callback.</param>
        public static void LoadAsync<T>(IMainUI view, Func<IEnumerable<T>> loadItems, Action<IEnumerable<T>> updateCollection, Action callback)
        {
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }

            if (loadItems == null)
            {
                throw new ArgumentNullException("loadItems");
            }

            view.EnableUIInteration(false);

            var backgroundWorker = new BackgroundWorker();

            DoWorkEventHandler onDoWork = (s, e) =>
            {
                e.Result = loadItems();
            };

            RunWorkerCompletedEventHandler onRunWorkerCompleted = (s, e) =>
            {
                if (e.Error != null)
                {
                    view.SetStatus(e.Error);
                }
                else if (updateCollection != null)
                {
                    updateCollection(e.Result as IEnumerable<T>);
                }

                if (callback != null)
                {
                    callback();
                }

                view.EnableUIInteration(true);
            };

            backgroundWorker.DoWork += onDoWork;
            backgroundWorker.RunWorkerCompleted += onRunWorkerCompleted;
            backgroundWorker.RunWorkerAsync();
        }

        /// <summary>
        /// Executes the async.
        /// </summary>
        /// <param name="executeAction">The execute action.</param>
        /// <param name="successCallback">The success callback.</param>
        /// <param name="failedCallback">The failed callback.</param>
        public static void ExecuteAsync(Action executeAction, Action successCallback, Action<Exception> failedCallback)
        {
            if (executeAction == null)
            {
                throw new ArgumentNullException("executeAction");
            }

            var backgroundWorker = new BackgroundWorker();

            DoWorkEventHandler onDoWork = (s, e) => executeAction();

            RunWorkerCompletedEventHandler onRunWorkerCompleted = (s, e) =>
            {
                if (e.Error != null && failedCallback != null)
                {
                    failedCallback(e.Error);
                }
                else if (successCallback != null)
                {
                    successCallback();
                }
            };

            backgroundWorker.DoWork += onDoWork;
            backgroundWorker.RunWorkerCompleted += onRunWorkerCompleted;
            backgroundWorker.RunWorkerAsync();
        }
    }
}
